package taishan

import (
	"sync"
)

const defaultHost = "_"

type RouterGroups struct {
	groups sync.Map
}

// GetAll 根据host获取路由组
// 1. 先获取通用路由组
// 2. 再获取特定域名路由组
func (that *RouterGroups) GetAll(host string) []*RouterGroup {
	groups := make([]*RouterGroup, 0)
	value, ok := that.groups.Load("")
	if ok {
		group := value.([]*RouterGroup)
		groups = append(groups, group...)
	}
	value, ok = that.groups.Load(host)
	if ok {
		group := value.([]*RouterGroup)
		groups = append(groups, group...)
	}
	return groups
}

// Get 获取一个域名下的所有Group
func (that *RouterGroups) Get(host string) []*RouterGroup {
	groups := make([]*RouterGroup, 0)
	value, ok := that.groups.Load(host)
	if ok {
		group := value.([]*RouterGroup)
		groups = append(groups, group...)
	}
	return groups
}

func (that *RouterGroups) Set(host string, groups []*RouterGroup) {
	that.groups.Store(host, groups)
}

// RouterGroup 路由组
// 根据path前缀或者路由pattern匹配
type RouterGroup struct {
	prefix      string
	middlewares []HandlerFunc
	engine      *Engine

	lock sync.Mutex
}

func (group *RouterGroup) Middleware(host, routeRule string, middlewares ...IMiddleware) error {
	return group.addMiddlewares(host, routeRule, middlewares...)
}

func (group *RouterGroup) addRoute(host, method, routeRule string, handler HandlerFunc) error {
	//todo
	//并发修改问题：当为空时同时set会导致数据不一致

	route := group.engine.routers.Get(host)
	if route != nil {
		return route.setRoute(method, routeRule, handler)
	}
	route = newRouter()
	err := route.setRoute(method, routeRule, handler)
	if err != nil {
		return err
	}
	group.lock.Lock()
	defer group.lock.Unlock()
	routeNew := group.engine.routers.Get(host)
	if routeNew != nil {
		return routeNew.setRoute(method, routeRule, handler)
	}
	group.engine.routers.Set(host, route)
	return nil
}

// 添加middlewares
func (group *RouterGroup) addMiddlewares(host, routeRule string, middlewares ...IMiddleware) error {
	route := group.engine.routers.Get(host)
	if route != nil {
		return route.setMiddlewares(routeRule, middlewares...)
	}
	group.lock.Lock()
	defer group.lock.Unlock()
	//双重验证
	route = group.engine.routers.Get(host)
	if route != nil {
		return route.setMiddlewares(routeRule, middlewares...)
	}
	route = newRouter()
	err := route.setMiddlewares(routeRule, middlewares...)
	if err != nil {
		return err
	}
	group.engine.routers.Set(host, route)
	return nil
}

func (group *RouterGroup) UpdateMiddlewareBatch(host string, rGroup *RouterGroup, middlewares ...HandlerFunc) {

}

// UpdateRouteBatch 批量更新
// 一次性更新相同host下的所有路由
func (group *RouterGroup) UpdateRouteBatch(host string, routeDatas []*RouteData) error {
	route := newRouter()
	for _, routeData := range routeDatas {

		err := route.setRoute(routeData.Method, routeData.RouteRule, routeData.Handler)
		if err != nil {
			return err
		}
	}

	group.engine.routers.Set(host, route)
	return nil
}

func (group *RouterGroup) All(host, routeRule string, handler HandlerFunc) error {
	return group.addRoute(host, "ALL", routeRule, handler)
}
func (group *RouterGroup) Get(host, routeRule string, handler HandlerFunc) error {
	return group.addRoute(host, "GET", routeRule, handler)
}
func (group *RouterGroup) Post(host, routeRule string, handler HandlerFunc) error {
	return group.addRoute(host, "POST", routeRule, handler)
}
func (group *RouterGroup) Route(host, method, routeRule string, handler HandlerFunc) error {
	return group.addRoute(host, method, routeRule, handler)
}
